package com.kmxd.ams.infra.logs.aop;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.kmxd.ams.client.archive.IArchiveTypeSvc;
import com.kmxd.ams.client.archive.vo.ArchiveTypeVO;
import com.kmxd.ams.client.logs.*;
import com.kmxd.ams.client.logs.dto.*;
import com.kmxd.ams.core.common.bo.LogArchBO;
import com.kmxd.ams.core.common.constant.ArchConst;
import com.kmxd.ams.core.common.enums.ArchOpEnum;
import com.kmxd.ams.core.common.enums.LogStatusEnum;
import com.kmxd.ams.core.common.enums.LoginStatusEnum;
import com.kmxd.ams.core.common.enums.SearchTypeEnum;
import com.kmxd.ams.core.log.annotation.ArchLogParameter;
import com.kmxd.ams.core.log.annotation.ArchLogParameters;
import com.kmxd.ams.core.log.annotation.AutoLog;
import com.kmxd.ams.core.util.ConvertUtil;
import com.kmxd.ams.core.util.IdUtil;
import com.kmxd.ams.core.util.IpUtil;
import com.kmxd.ams.core.util.SecurityUtil;
import com.kmxd.ams.infra.archive.entity.ArchiveType;
import com.kmxd.ams.infra.logs.entity.LogErecord;
import com.kmxd.ams.infra.oss.entity.EfileRecord;
import java.net.InetAddress;
import java.util.*;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.MDC;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Component;
import org.springframework.validation.BindingResult;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;

/**
 * 日志实现方法
 *
 * @author ZuoLG
 */
@Slf4j
@Component
public class LogsCmd {

  /**
   * 系统操作日志
   *
   * @param joinPoint
   * @param e
   * @param retValue
   * @param time
   */
  public void logsSystem(
      AutoLog autoLog, final JoinPoint joinPoint, final Exception e, Object retValue, long time) {
    try {
      // 获得注解
      if (Objects.isNull(autoLog)) {
        return;
      }
      HttpServletRequest request =
          ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
      LogSystemAddDTO sysLog = new LogSystemAddDTO();
      sysLog.setLevel(autoLog.level().getCode());
      sysLog.setLogModule(autoLog.module());
      sysLog.setLogTitle(autoLog.title());
      sysLog.setLogStatus(LogStatusEnum.SUCCESS.getCode());
      sysLog.setUserPlatform(autoLog.userPlatform().getCode());
      sysLog.setRequsetUri(request.getRequestURI());
      sysLog.setRequsetType(request.getMethod());
      // 设置方法名称
      String className = joinPoint.getTarget().getClass().getName();
      String methodName = joinPoint.getSignature().getName();
      sysLog.setRequsetMethod(className + "." + methodName + "()");

      if (autoLog.isSaveRequestData()) {
        List<Object> objectList =
            Arrays.stream(joinPoint.getArgs())
                .filter(item -> Objects.nonNull(item) && !isFilterObject(item))
                .collect(Collectors.toList());
        sysLog.setRequsetParams(JSONUtil.toJsonStr(objectList));
      }
      if (autoLog.isSaveResponseData()) {
        sysLog.setResponseResult(StrUtil.sub(JSONUtil.toJsonStr(retValue), 0, 5000));
      }
      sysLog.setRequsetTime(String.valueOf(time));
      if (StpUtil.isLogin()) {
        sysLog.setIpAddress(SecurityUtil.getLoginUser().getIpAddress());
        sysLog.setOperLocation(SecurityUtil.getLoginUser().getLoginLocation());
        sysLog.setBrowser(SecurityUtil.getLoginUser().getBrowser());
        sysLog.setOs(SecurityUtil.getLoginUser().getOs());
        sysLog.setOperName(SecurityUtil.getUsername());
        sysLog.setComId(SecurityUtil.getCropId());
        sysLog.setFondsId(SecurityUtil.getFondsId());
        sysLog.setDeptId(SecurityUtil.getLoginUser().getDeptId());
        sysLog.setDeptName(SecurityUtil.getLoginUser().getDeptName());
      }
      if (e != null) {
        sysLog.setLogStatus(LogStatusEnum.FAILURE.getCode());
        sysLog.setException(e.getMessage());
      }
      ThreadUtil.execAsync(
          () -> {
            ILogSystemSvc sysLogService = SpringUtil.getBean(ILogSystemSvc.class);
            sysLogService.add(sysLog);
          });
      log.debug(
          "URI：{}，模块：{}，功能：{}，执行耗时：{}",
          sysLog.getRequsetUri(),
          sysLog.getLogModule(),
          sysLog.getLogTitle(),
          time >= 1000 ? time / 1000 + "s" : time + "ms");
    } catch (Exception exception) {
      log.error("异常信息:{}", exception.getMessage());
      exception.printStackTrace();
    }
  }

  /**
   * 登录
   *
   * @param joinPoint
   * @param e
   * @param retValue
   * @param time
   */
  public void logsLogin(
      AutoLog autoLog, final JoinPoint joinPoint, final Exception e, Object retValue, long time) {
    try {
      // 获得注解
      if (Objects.isNull(autoLog)) {
        return;
      }
      LogLoginAddDTO sysLog = new LogLoginAddDTO();
      sysLog.setLevel(autoLog.level().getCode());
      if (StpUtil.isLogin()) {
        try {
          sysLog.setComId(SecurityUtil.getCropId());
          sysLog.setFondsId(SecurityUtil.getFondsId());
          sysLog.setDeptId(SecurityUtil.getLoginUser().getDeptId());
          sysLog.setDeptName(SecurityUtil.getLoginUser().getDeptName());
          sysLog.setUserCode(SecurityUtil.getUsername());
          sysLog.setUserName(SecurityUtil.getLoginUser().getRealName());
          sysLog.setIp(SecurityUtil.getLoginUser().getIpAddress());
          // 登录方式：账号密码登录，SSO登录、短信登录、直接退出、超时退出、重复登录退出等； */
          // 记录token中登录时间 */
          sysLog.setTokenTime(DateUtil.formatDateTime(SecurityUtil.getLoginUser().getLoginTime()));
          sysLog.setClient(SecurityUtil.getLoginUser().getOs());
        } catch (Exception ex) {
          log.info("获取用户相关信息异常:{}", e.getMessage());
        }
      }
      sysLog.setLoginMode("账号密码登录");
      // 获取本地IP对象
      InetAddress ia1 = InetAddress.getLocalHost();
      sysLog.setMacaddr(IpUtil.getMACAddress(ia1));
      sysLog.setOptType(autoLog.title());
      if (autoLog.isSaveRequestData()) {
        List<Object> objectList =
            Arrays.stream(joinPoint.getArgs())
                .filter(item -> Objects.nonNull(item) && !isFilterObject(item))
                .collect(Collectors.toList());
        sysLog.setRemarks(JSONUtil.toJsonStr(objectList));
      }
      if (e != null) {
        sysLog.setOpStatus(LoginStatusEnum.LOGIN_FAILED.getCode());
        sysLog.setOpTime(new Date());
        sysLog.setRemarks(e.getMessage());
      } else {
        sysLog.setOpStatus(LoginStatusEnum.LOGIN_SUCCESSFUL.getCode());
        sysLog.setOpTime(new Date());
      }
      ThreadUtil.execAsync(
          () -> {
            ILogLoginSvc sysLogService = SpringUtil.getBean(ILogLoginSvc.class);
            sysLogService.add(sysLog);
          });
      log.debug(
          "IP：{}，登录用户：{}，用户姓名：{}，执行耗时：{}",
          sysLog.getIp(),
          sysLog.getUserCode(),
          sysLog.getUserName(),
          time >= 1000 ? time / 1000 + "s" : time + "ms");
    } catch (Exception exception) {
      log.error("异常信息:{}", exception.getMessage());
      exception.printStackTrace();
    }
  }

  /** 档案维护 */
  public void logsArchive(
      ArchLogParameter autoLog,
      final JoinPoint joinPoint,
      final Exception e,
      Object retValue,
      long time) {
    try {
      // 获得注解
      Signature signature = joinPoint.getSignature();
      MethodSignature methodSignature = (MethodSignature) signature;
      if (Objects.isNull(autoLog)) {
        return;
      }
      String params = getParams(joinPoint);
      HttpServletRequest request =
          ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
      LogArchiveAddDTO archLog = new LogArchiveAddDTO();
      archLog.setLevel(autoLog.level().getCode());
      archLog.setOpName(autoLog.title());
      archLog.setController(request.getRequestURI());
      archLog.setAction(methodSignature.getMethod().getName());
      archLog.setOpTime(new Date());
      JSONObject parseObj = JSONUtil.parseObj(params);
      String updateData = MDC.get(ArchConst.UPDATE_DATA + parseObj.get(ArchConst.DEF_ID));
      if (StrUtil.isNotBlank(updateData)) {
        JSONObject obj = JSONUtil.parseObj(updateData);
        archLog.setArchId(obj.get(ArchConst.DEF_ID, Long.class));
        archLog.setTableId(obj.get(ArchConst.TABLE_ID, String.class));
        archLog.setArchTypeId(obj.get(ArchConst.ARCH_TYPE_ID, Long.class));
        archLog.setYear(obj.get(ArchConst.FIELD_YEAR, String.class));
        archLog.setArchTitle(obj.get(ArchConst.FIELD_TITLE, String.class));
        archLog.setArchCode(obj.get(ArchConst.ARCH_CODE, String.class));
        archLog.setSecurity(obj.get(ArchConst.FIELD_SECURITY, String.class));
        archLog.setRetentionPeriod(obj.get(ArchConst.FIELD_RETENTION_PERIOD, String.class));
      }
      if (StpUtil.isLogin()) {
        archLog.setComId(SecurityUtil.getCropId());
        archLog.setFondsId(SecurityUtil.getFondsId());
        archLog.setDeptId(SecurityUtil.getLoginUser().getDeptId());
        archLog.setDeptName(SecurityUtil.getLoginUser().getDeptName());
        archLog.setUserCode(SecurityUtil.getUsername());
        archLog.setUserName(SecurityUtil.getLoginUser().getRealName());
        archLog.setUserId(SecurityUtil.getUserId());
        archLog.setIp(SecurityUtil.getLoginUser().getIpAddress());
      }
      ArchLogParameters parameters =
          AnnotationUtils.findAnnotation(methodSignature.getMethod(), ArchLogParameters.class);
      List<ArchLogParameter> logParameters = Lists.newArrayList();
      if (Objects.nonNull(parameters) && ObjectUtil.isNotEmpty(parameters.value())) {
        logParameters.addAll(Arrays.asList(parameters.value()));

      } else {
        ArchLogParameter parameter =
            AnnotationUtils.findAnnotation(methodSignature.getMethod(), ArchLogParameter.class);
        if (Objects.nonNull(parameter)) {
          logParameters.add(parameter);
        }
      }
      logParameters.forEach(
          item -> {
            ArchOpEnum op = item.op();
            List<LogArchBO> typeList = op.getTypeList();
            typeList.forEach(
                type -> {
                  LogArchiveAddDTO log = ConvertUtil.toBean(archLog, LogArchiveAddDTO.class);
                  log.setType(type.getType().getType());
                  log.setTypeName(type.getType().getDesc());
                  log.setOpType(type.getOpType());
                  log.setOpTypeName(type.getOpTypeName());
                  log.setOp(item.op().getCode());
                  log.setOpName(item.op().getDesc());
                  log.setActionDescription(item.content());
                  log.setId(null);
                  ThreadUtil.execAsync(
                      () -> {
                        ILogArchiveSvc logService = SpringUtil.getBean(ILogArchiveSvc.class);
                        logService.add(log);
                      });
                });
          });

      log.debug(
          "用户名：{}，姓名：{}，类型：{}，执行耗时：{}",
          archLog.getUserCode(),
          archLog.getUserName(),
          archLog.getArchTypeName(),
          time >= 1000 ? time / 1000 + "s" : time + "ms");
    } catch (Exception exception) {
      log.error("异常信息:{}", exception.getMessage());
      exception.printStackTrace();
    }
  }

  /** 档案利用 */
  public void logsArchiveUse(
      AutoLog autoLog, final JoinPoint joinPoint, final Exception e, Object retValue, long time) {

    try {
      // 获得注解
      if (Objects.isNull(autoLog)) {
        return;
      }
      HttpServletRequest request =
          ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
      String params = getParams(joinPoint);
      LogArchiveUseAddDTO searchLog = new LogArchiveUseAddDTO();
      searchLog.setLevel(autoLog.level().getCode());
      if (autoLog.isSaveResponseData()) {
        log.debug("{}", autoLog.isSaveOldRecord());
      }

      searchLog.setCreateTime(new Date());
      searchLog.setOp(autoLog.opType());
      JSONObject parseObj = JSONUtil.parseObj(params);
      searchLog.setTableId(parseObj.getStr(ArchConst.TABLE_ID));
      searchLog.setArchId(parseObj.getLong(ArchConst.DEF_ID));
      Long id = parseObj.getLong(ArchConst.DEF_ID);
      if (Objects.isNull(id)) {
        String reqId = request.getParameter(ArchConst.DEF_ID);
        if (StrUtil.isNotBlank(reqId)) {
          id = Long.parseLong(reqId);
        }
      }
      String updateData = MDC.get(ArchConst.USE_DATA + id);
      if (StrUtil.isNotBlank(updateData)) {
        JSONObject obj = JSONUtil.parseObj(updateData);
        searchLog.setArchId(obj.get(ArchConst.DEF_ID, Long.class));
        Long archTypeId = obj.get(ArchConst.ARCH_TYPE_ID, Long.class);
        if (Objects.isNull(archTypeId)) {
          String reqArchTypeId = request.getParameter(ArchConst.ARCH_TYPE_ID);
          if (StrUtil.isNotBlank(reqArchTypeId)) {
            archTypeId = Long.parseLong(reqArchTypeId);
          } else {
            Long currentArchTypeId = parseObj.getLong(ArchConst.ARCH_TYPE_ID);
            if (Objects.nonNull(currentArchTypeId)) {
              archTypeId = currentArchTypeId;
            }
          }
        }
        searchLog.setArchTypeId(archTypeId);
        if (Objects.nonNull(archTypeId)) {
          searchLog.setArchTypeId(archTypeId);
          IArchiveTypeSvc archiveTypeSvc = SpringUtil.getBean(IArchiveTypeSvc.class);
          ArchiveType archiveType = archiveTypeSvc.getById(archTypeId);
          String volPrefix = archiveType.getHaveVol() ? "卷内" : "";
          String name = archiveType.getName();
          name = name + "-" + volPrefix + "文件";
          searchLog.setArchTypeName(name);
        }

        String tableId = obj.get(ArchConst.TABLE_ID, String.class);

        if (Objects.isNull(tableId)) {
          String reqTableId = request.getParameter(ArchConst.TABLE_ID);
          if (StrUtil.isNotBlank(reqTableId)) {
            tableId = reqTableId;
          } else {
            String currentTableId = parseObj.getStr(ArchConst.TABLE_ID);
            if (StrUtil.isNotBlank(currentTableId)) {
              tableId = currentTableId;
            }
          }
        }
        searchLog.setTableId(tableId);
        // 来源
        searchLog.setSource("本单位");
        // 利用目的
        searchLog.setPurpose(obj.get("purpose", String.class));
        // 授权信息
        searchLog.setAuthorize(
            Optional.ofNullable(obj.get("authorize", String.class)).orElse("公有授权"));
        // 备注
        searchLog.setRemarks(obj.get("remarks", String.class));
        searchLog.setYear(obj.get(ArchConst.FIELD_YEAR, Integer.class));
        searchLog.setArchTitle(obj.get(ArchConst.FIELD_TITLE, String.class));
      }
      if (StpUtil.isLogin()) {
        searchLog.setUserId(SecurityUtil.getUserId());
        searchLog.setComId(SecurityUtil.getCropId());
        searchLog.setFondsId(SecurityUtil.getFondsId());
        searchLog.setDeptId(SecurityUtil.getLoginUser().getDeptId());
        searchLog.setDeptName(SecurityUtil.getLoginUser().getDeptName());
        searchLog.setUserCode(SecurityUtil.getUsername());
        searchLog.setUserName(SecurityUtil.getLoginUser().getRealName());
        searchLog.setIp(SecurityUtil.getLoginUser().getIpAddress());
      }
      searchLog.setId(null);

      ThreadUtil.execAsync(
          () -> {
            ILogArchiveUseSvc logService = SpringUtil.getBean(ILogArchiveUseSvc.class);
            logService.add(searchLog);
          });

      log.debug(
          "用户名：{}，姓名：{}，类型：{}，执行耗时：{}",
          searchLog.getUserCode(),
          searchLog.getUserName(),
          searchLog.getOp(),
          time >= 1000 ? time / 1000 + "s" : time + "ms");
    } catch (Exception exception) {
      log.error("异常信息:{}", exception.getMessage());
      exception.printStackTrace();
    }
  }

  /** 电子档案 */
  public void logsElectronicRecord(
      AutoLog autoLog, final JoinPoint joinPoint, final Exception e, Object retValue, long time) {
    try {
      // 获得注解
      if (Objects.isNull(autoLog)) {
        return;
      }
      HttpServletRequest request =
          ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
      String params = getParams(joinPoint);
      LogErecordAddDTO searchLog = new LogErecordAddDTO();
      searchLog.setLevel(autoLog.level().getCode());
      if (autoLog.isSaveResponseData()) {
        log.debug("{}", autoLog.isSaveOldRecord());
      }
      searchLog.setCreateTime(new Date());
      searchLog.setOp(autoLog.opType());
      JSONObject parseObj = JSONUtil.parseObj(params);
      searchLog.setTableId(parseObj.getStr(ArchConst.TABLE_ID));
      searchLog.setRecordId(parseObj.getLong(ArchConst.DEF_ID));

      if (StpUtil.isLogin()) {
        searchLog.setUserId(SecurityUtil.getUserId());
        searchLog.setComId(SecurityUtil.getCropId());
        searchLog.setFondsId(SecurityUtil.getFondsId());
        searchLog.setDeptId(SecurityUtil.getLoginUser().getDeptId());
        searchLog.setDeptName(SecurityUtil.getLoginUser().getDeptName());
        searchLog.setUserCode(SecurityUtil.getUsername());
        searchLog.setUserName(SecurityUtil.getLoginUser().getRealName());
        searchLog.setIp(SecurityUtil.getLoginUser().getIpAddress());
      }

      Integer opStatus = Objects.isNull(e) ? 1 : 0;
      searchLog.setOpStatus(opStatus);

      searchLog.setId(null);
      String idsStr = request.getParameter("id");
      Long id = StrUtil.isBlank(idsStr) ? null : Long.valueOf(idsStr);
      List<LogErecord> logList = Lists.newArrayList();
      String ids = request.getParameter("ids");
      if (StrUtil.isBlank(ids)) {
        String sortIds = buildUpdateSortIds(parseObj);
        if (StrUtil.isNotBlank(sortIds)) {
          ids = sortIds;
        }
      }
      String archTypeId = MDC.get(ArchConst.ARCH_TYPE_ID);
      if (Objects.nonNull(id)) {
        buildEFileInfo(searchLog, id);
      } else if (StrUtil.isNotBlank(ids)) {
        Set<Long> idList = IdUtil.split(ids);
        idList.forEach(
            currentId -> {
              searchLog.setArchTypeId(null);
              buildEFileInfo(searchLog, currentId);
              if (Objects.nonNull(searchLog.getArchTypeId())) {
                LogErecord dto = ConvertUtil.toBean(searchLog, LogErecord.class);
                logList.add(dto);
              }
            });
      } else {
        Long currentArchTypeId = StrUtil.isBlank(archTypeId) ? null : Long.parseLong(archTypeId);
        searchLog.setArchTypeId(currentArchTypeId);
        String archId = MDC.get(ArchConst.ARCH_ID);
        if (StrUtil.isNotBlank(archId) && NumberUtil.isNumber(archId)) {
          searchLog.setDocId(Long.parseLong(Optional.ofNullable(archId).orElse("")));
        }
        IArchiveTypeSvc archiveTypeSvc = SpringUtil.getBean(IArchiveTypeSvc.class);
        ArchiveTypeVO view = archiveTypeSvc.view(currentArchTypeId);
        if (ObjectUtil.isNotEmpty(view)) {
          searchLog.setTableId(view.getDocTableId());
        }
      }
      ThreadUtil.execAsync(
          () -> {
            ILogErecordSvc logService = SpringUtil.getBean(ILogErecordSvc.class);
            if (ObjectUtil.isNotEmpty(logList)) {
              logService.saveBatch(logList);
            } else {
              logService.add(searchLog);
            }
          });

      log.debug(
          "用户名：{}，姓名：{}，类型：{}，执行耗时：{}",
          searchLog.getUserCode(),
          searchLog.getUserName(),
          searchLog.getOp(),
          time >= 1000 ? time / 1000 + "s" : time + "ms");
    } catch (Exception exception) {
      log.error("异常信息:{}", exception.getMessage());
      exception.printStackTrace();
    }
  }

  /**
   * 更新排序的条目
   *
   * @param parseObj
   * @return
   */
  private String buildUpdateSortIds(JSONObject parseObj) {

    // 排序ids拼接
    JSONArray itemLists = parseObj.getJSONArray("itemLists");
    if (Objects.isNull(itemLists)) {
      return null;
    }
    String sortIds =
        itemLists.stream()
            .map(
                item -> {
                  JSONObject sortItem = JSONUtil.parseObj(item);
                  String sortId = sortItem.getStr(ArchConst.DEF_ID);
                  return sortId;
                })
            .collect(Collectors.joining(","));
    return sortIds;
  }

  private void buildEFileInfo(LogErecordAddDTO searchLog, Long id) {
    String str = MDC.get(id.toString());
    if (StrUtil.isBlank(str)) {
      return;
    }
    EfileRecord efileRecord = JSONUtil.toBean(str, EfileRecord.class);
    searchLog.setRecordId(efileRecord.getId());
    searchLog.setDocId(efileRecord.getArchId());
    searchLog.setFileName(efileRecord.getSaveFileName());
    searchLog.setArchTypeId(efileRecord.getArchTypeId());
    IArchiveTypeSvc archiveTypeSvc = SpringUtil.getBean(IArchiveTypeSvc.class);
    ArchiveTypeVO view = archiveTypeSvc.view(efileRecord.getArchTypeId());
    searchLog.setTableId(view.getDocTableId());
  }

  /** 检索 */
  public void logsSearch(
      AutoLog autoLog, final JoinPoint joinPoint, final Exception e, Object retValue, long time) {
    try {
      // 获得注解
      if (Objects.isNull(autoLog)) {
        return;
      }
      String params = getParams(joinPoint);
      LogSearchAddDTO searchLog = new LogSearchAddDTO();
      searchLog.setLevel(autoLog.level().getCode());
      if (autoLog.isSaveResponseData()) {
        log.debug("{}", autoLog.isSaveOldRecord());
      }
      searchLog.setCreateTime(new Date());
      JSONObject parseObj = JSONUtil.parseObj(params);
      Long archTypeId = parseObj.getLong(ArchConst.ARCH_TYPE_ID);
      searchLog.setArchTypeId(archTypeId);
      if (Objects.nonNull(archTypeId)) {
        IArchiveTypeSvc archiveTypeSvc = SpringUtil.getBean(IArchiveTypeSvc.class);
        ArchiveTypeVO view = archiveTypeSvc.view(archTypeId);
        if (Objects.nonNull(view)) {
          searchLog.setArchTypeName(view.getName());
        }
      }

      searchLog.setTableId(parseObj.getStr(ArchConst.TABLE_ID));
      String title = parseObj.getStr(ArchConst.FIELD_TITLE);
      String keyword = parseObj.getStr(ArchConst.SEARCH_KEYWORD);
      String year = parseObj.getStr(ArchConst.FIELD_YEAR);
      boolean haveCondition = parseObj.containsKey(ArchConst.SEARCH_CONDITION);
      if (haveCondition) {
        Object o = parseObj.get(ArchConst.SEARCH_CONDITION);
        if (o instanceof JSONObject) {
          JSONObject condition = (JSONObject) o;
          if (StrUtil.isBlank(title)) {
            title = condition.getStr(ArchConst.FIELD_TITLE);
          }
          if (StrUtil.isBlank(keyword)) {
            keyword = condition.getStr(ArchConst.SEARCH_KEYWORD);
          }
          if (StrUtil.isBlank(year)) {
            year = condition.getStr(ArchConst.FIELD_YEAR);
          }
        }
      }
      String remarks =
          StrUtil.isAllBlank(title, keyword, year)
              ? null
              : StrUtil.concat(true, title, keyword, year);
      searchLog.setRemarks(remarks);
      if (StpUtil.isLogin()) {
        searchLog.setUserId(SecurityUtil.getUserId());
        searchLog.setComId(SecurityUtil.getCropId());
        searchLog.setFondsId(SecurityUtil.getFondsId());
        searchLog.setDeptId(SecurityUtil.getLoginUser().getDeptId());
        searchLog.setDeptName(SecurityUtil.getLoginUser().getDeptName());
        searchLog.setUserCode(SecurityUtil.getUsername());
        searchLog.setUserName(SecurityUtil.getLoginUser().getRealName());
        searchLog.setIp(SecurityUtil.getLoginUser().getIpAddress());
      }
      searchLog.setSearchCondition(params);
      SearchTypeEnum type = SearchTypeEnum.convert(autoLog.title());
      int searchType = Objects.nonNull(type) ? type.getCode() : 1;
      searchLog.setType(searchType);
      searchLog.setId(null);
      ThreadUtil.execAsync(
          () -> {
            ILogSearchSvc logService = SpringUtil.getBean(ILogSearchSvc.class);
            logService.add(searchLog);
          });

      log.debug(
          "用户名：{}，姓名：{}，类型：{}，执行耗时：{}",
          searchLog.getUserCode(),
          searchLog.getUserName(),
          searchLog.getArchTypeName(),
          time >= 1000 ? time / 1000 + "s" : time + "ms");
    } catch (Exception exception) {
      log.error("异常信息:{}", exception.getMessage());
      exception.printStackTrace();
    }
  }

  /**
   * 判断是否需要过滤的对象。
   *
   * @param o 对象信息。
   * @return 如果是需要过滤的对象，则返回true；否则返回false。
   */
  public boolean isFilterObject(final Object o) {
    Class<?> clazz = o.getClass();
    if (clazz.isArray()) {
      return clazz.getComponentType().isAssignableFrom(MultipartFile.class);
    } else if (Collection.class.isAssignableFrom(clazz)) {
      Collection collection = (Collection) o;
      for (Object value : collection) {
        return value instanceof MultipartFile;
      }
    } else if (Map.class.isAssignableFrom(clazz)) {
      Map map = (Map) o;
      for (Object value : map.entrySet()) {
        Map.Entry entry = (Map.Entry) value;
        return entry.getValue() instanceof MultipartFile;
      }
    }
    return o instanceof MultipartFile
        || o instanceof HttpServletRequest
        || o instanceof HttpServletResponse
        || o instanceof BindingResult
        || o instanceof Page;
  }

  private String getParams(JoinPoint joinPoint) {
    HttpServletRequest request =
        ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
    Map<String, String[]> map = request.getParameterMap();
    if (ObjectUtil.isNotEmpty(map)) {
      return JSONUtil.toJsonStr(map);
    } else {
      Object args = joinPoint.getArgs();
      if (Objects.nonNull(args)) {
        return argsArrayToString(joinPoint.getArgs());
      }
    }
    return "";
  }

  /** 参数拼装 */
  private String argsArrayToString(Object[] paramsArray) {
    String params = "";
    if (paramsArray != null) {
      for (Object o : paramsArray) {
        if (Objects.nonNull(o) && !isFilterObject(o)) {
          try {
            Object jsonObj = JSONUtil.toJsonStr(o);
            params += jsonObj.toString() + " ";
          } catch (Exception e) {
          }
        }
      }
    }
    return params.trim();
  }
}
